package view;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.font.TextAttribute;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Map;

import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

import com.alee.extended.window.ComponentMoveAdapter;
import com.alee.laf.WebLookAndFeel;
import com.alee.laf.rootpane.WebFrame;

import controller.Controls;

/**
 * WeaveGUI contains main JFrame for whole application. It provides methods to
 * alter its head and body panels.
 * 
 * @author Matt Adams
 * @version 1.0
 */
public class RecipeGUI {
    private static final String[] NAV_BUTTONS = {"Recently Viewed", "Favorites", "Search", "Add Recipe", "Logout"};
    private static final String INITIAL_BACKGROUND = "Backgrounds/initialBackground.jpg";
    private static final String MAIN_BACKGROUND = "Backgrounds/cutting_board.jpg";
    private static final String FOOTER = "Backgrounds/recipeFooterBg.png";
    private static final String HEADER = "Backgrounds/recipeNavigationBg.png";
    private static final String BODY = "Backgrounds/recipeMainContentBg.png";
    private static final Dimension FRAME_DIM = new Dimension(800, 650);
    private Controls my_controller;
    private JFrame my_frame;
    private JPanel my_header;
    private JPanel my_body;
    private JPanel my_bodySetup;
    private AlphaContainer my_navPanel;
    private BackgroundPanel my_footer;
    private BackgroundPanel my_main_back;
    private BackgroundPanel my_body_back;

    /**
     * Constructs main frame and sets controller reference.
     * 
     * @param controller Reference to controller.
     */
    public RecipeGUI(Controls controller) {
        my_controller = controller;
        my_main_back = new BackgroundPanel(BackgroundPanel.createBackgroundImage(my_main_back, INITIAL_BACKGROUND), 0);
        my_frame = new JFrame("Recipes");
        my_navPanel = buildNavButtons();
    }
    /**
     * Creates view displayed at application launch.
     */
    public void createInitialView() {
        //my_main_back.setLayout(new BoxLayout(my_main_back, BoxLayout.LINE_AXIS));
        my_main_back.add(new LoginPanel(my_controller), BorderLayout.CENTER);
        my_main_back.setPreferredSize(FRAME_DIM);
        my_frame.add(my_main_back);
        my_frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        my_frame.setPreferredSize(FRAME_DIM);
        my_frame.pack();
        my_frame.setLocationRelativeTo(null);
        my_frame.setVisible(true);
        //my_frame.setMinimumSize(my_frame.getSize());
    }
    /**
     * Creates view after a user has logged in.
     */
    public void createView() {
        my_main_back.removeAll();
        my_main_back.setImage(BackgroundPanel.createBackgroundImage(my_main_back, MAIN_BACKGROUND));
        my_bodySetup = setupBodyBack(); // sets up gridBagLayout
        //my_header = new HeaderPanel(my_controller);
        //my_body = new RecipeListPanel(my_controller, my_controller.getRecentlyViewed(), "Recently Viewed");
        my_body = new RecipeListPanel(my_controller, my_controller.getRecentlyViewed(), "Recently Viewed");
        my_body_back.add(my_body);
        //my_main_back.add(my_header, BorderLayout.NORTH);
        my_main_back.setLayout(new BoxLayout(my_main_back, BoxLayout.PAGE_AXIS));
        my_main_back.add(my_bodySetup);
        my_frame.setPreferredSize(new Dimension(my_frame.getWidth(), my_frame.getHeight()));
        my_frame.pack();
        //my_frame.setSize(my_frame.getWidth(), my_frame.getHeight());
        //my_frame.setMinimumSize(my_frame.getSize());
        /*my_frame.add(my_main_back);
        my_frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        my_frame.setPreferredSize(FRAME_DIM);
        my_frame.pack();
        my_frame.setLocationRelativeTo(null);
        my_frame.setVisible(true);
        my_frame.setMinimumSize(my_frame.getSize());/*
        //Adds Dimming affect
        //my_frame.getRootPane().setGlassPane(new JComponent() {
            /** Serialized ID*/
            /*private static final long serialVersionUID = -1638652874019126124L;

            public void paintComponent(Graphics g) {
                g.setColor(new Color(0, 0, 0, 100));
                g.fillRect(0, 0, getWidth(), getHeight());
                super.paintComponent(g);
            }
        });*/
    }

    /**
     * Sets body of this frame to the provided JPanel.
     * 
     * @param panel JPanel to be displayed.
     */
    public void setBody(JPanel the_panel) {
        /*if (my_body_back.getComponent(0) instanceof DefaultBody && !(panel instanceof DefaultBody)) {
            DefaultBody deBody = (DefaultBody) my_body_back.getComponent(0);
            deBody.getFadePanel().endFadeTimer();
        }*/
        my_body_back.removeAll();
        my_body = the_panel;
        my_body_back.add(my_body);
        my_frame.setPreferredSize(new Dimension(my_frame.getWidth(), my_frame.getHeight()));
        my_frame.pack();
    }
    public void logout() {
        my_main_back.removeAll();
        my_main_back.setImage(BackgroundPanel.createBackgroundImage(my_main_back, INITIAL_BACKGROUND));
        my_main_back.setLayout(new BorderLayout());
        my_main_back.add(new LoginPanel(my_controller), BorderLayout.CENTER);
        my_frame.pack();
    }
    /**
     * Displays warning message for a bad login attempt.
     */
    public void badLogin() {
        JOptionPane.showMessageDialog(my_frame, "Invalid Username and Password",
                                      "Input Error", JOptionPane.WARNING_MESSAGE);
    }

    /**
     * Displays warning message for repository error, then closes the program.
     * 
     * @param error Error message to be displayed.
     */
    public void showError(String error) {
        JOptionPane.showMessageDialog(my_frame, error, "Database Error",
                                      JOptionPane.WARNING_MESSAGE);
    }
    private JPanel setupBodyBack() {
        my_body_back = new BackgroundPanel(BackgroundPanel.createBackgroundImage(my_body_back, BODY), 0);
        my_body_back.setOpaque(false);
        my_header = new BackgroundPanel(BackgroundPanel.createBackgroundImage(my_body_back, HEADER), 0);
        my_footer = new BackgroundPanel(BackgroundPanel.createBackgroundImage(my_body_back, FOOTER), 0);
        my_header.setOpaque(false);
        my_footer.setOpaque(false);
        my_header.add(my_navPanel);
        my_header.setPreferredSize(new Dimension(500, 40));
        my_header.setMaximumSize(new Dimension(900, 40));
        my_footer.setPreferredSize(new Dimension(500, 40));
        my_footer.setMaximumSize(new Dimension(900, 20));
        my_body_back.setPreferredSize(new Dimension(500, 500));
        
        JPanel mainBody = new JPanel();
        mainBody.setLayout(new BoxLayout(mainBody, BoxLayout.Y_AXIS));
        mainBody.add(my_header);
        mainBody.add(my_body_back);
        mainBody.add(my_footer);
        mainBody.setBorder(BorderFactory.createEmptyBorder(40,80,40,80));
        mainBody.setMaximumSize(new Dimension(900, 900));
        
        /*mainBody.setLayout(new GridBagLayout());
        GridBagConstraints c = new GridBagConstraints();
        c.fill = GridBagConstraints.HORIZONTAL;
        c.anchor = GridBagConstraints.CENTER;
        c.gridx = 0;
        c.gridy = 0;
        c.ipady = 15;
        mainBody.add(body_header, c);
        c.fill = GridBagConstraints.HORIZONTAL;
        c.ipady = 0;
        c.gridx = 0;
        c.gridy = 1;
        mainBody.add(my_body_back, c);
        c.fill = GridBagConstraints.HORIZONTAL;
        c.gridx = 0;
        c.gridy = 2;
        c.ipady = 75;
        mainBody.add(my_footer, c);
        setupFooter();*/
        return mainBody;
    }
    private AlphaContainer buildNavButtons() {
        JPanel navPanel = new JPanel();
        navPanel.setLayout(new BoxLayout(navPanel, BoxLayout.X_AXIS));
        navPanel.setBackground((new Color(128, 128, 128)));
        for(int i = 0; i < NAV_BUTTONS.length; i++) {
             JPanel square = new JPanel();
             square.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
             square.setOpaque(false);
             final JLabel navButton = new JLabel(NAV_BUTTONS[i]);
             navButton.setBorder(BorderFactory.createEmptyBorder(5, 0, 0, 0));
             navButton.setFont(new Font(Font.SANS_SERIF, Font.PLAIN, 16));
             navButton.setForeground(Color.WHITE);
             final Font originalfont = navButton.getFont();
             navButton.addMouseListener(new MouseListener() {
                    @Override
                    public void mouseClicked(MouseEvent arg0) {                      
                    }
                    @SuppressWarnings({ "rawtypes", "unchecked" })
                    @Override
                    public void mouseEntered(MouseEvent arg0) {
                        Map attributes = originalfont.getAttributes();
                        attributes.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON);
                        arg0.getComponent().setFont(originalfont.deriveFont(attributes));  
                    }
                    @Override
                    public void mouseExited(MouseEvent arg0) {
                        arg0.getComponent().setFont(originalfont);
                    }
                    @Override
                    public void mousePressed(MouseEvent arg0) {
                        // Do nothing   
                    }
                    @Override
                    public void mouseReleased(MouseEvent arg0) {
                        if (((JLabel) arg0.getSource()).getText().equals(NAV_BUTTONS[0])) {
                            my_controller.goRecentlyViewed();
                        } else if (((JLabel) arg0.getSource()).getText().equals(NAV_BUTTONS[1])) {
                            my_controller.goFavorites();
                        } else if (((JLabel) arg0.getSource()).getText().equals(NAV_BUTTONS[2])) {
                            my_controller.goSearch();
                        } else if (((JLabel) arg0.getSource()).getText().equals(NAV_BUTTONS[3])) {
                            my_controller.goAddRecipe();
                        } else if (((JLabel) arg0.getSource()).getText().equals(NAV_BUTTONS[4])) {
                            my_controller.logout();
                        }  
                    }
                });
            square.add(navButton);
            navPanel.add(square);
        }
        AlphaContainer alphaHolder = new AlphaContainer(navPanel);
        return alphaHolder;
    }
    public BackgroundPanel getMainBack() {
        return my_main_back;
    }
    public JFrame getFrame() {
        return my_frame;
    }
}
